<template>
  <div class="form-comp">
    <div class="toolbar-item toolbar-select">
      <el-tree
          ref="treeRef"
          :data="compData"
          :check-strictly="true"
          :show-checkbox="showCheckBox"
          node-key="key"
          :default-expanded-keys="expandedKeys"
          @check="checkEvent"
          @node-click="nodeClick"
          highlight-current
          :default-checked-keys="compValue"
          :props="defaultProps"
      />
    </div>

  </div>

</template>

<script lang="ts" setup>
//定义组件名称
defineOptions({
  name: "FormMenuTree"
});
// @ts-ignore
import {ref, onMounted, getCurrentInstance, watchEffect, watch} from 'vue'

const props = defineProps({
  value: {type: String, required: true},
  checkbox: {type: Boolean, required: false},
  disabled: {type: Boolean, required: false},
  roleId: {type: String, required: false},
});

const treeRef = ref<any>(null);

const showCheckBox = ref(false);
//组件的值
const compValue = ref([]);

const emit = defineEmits(['update:value'])

const compData = ref<any>();
const expandedKeys=ref(['1','2','3']);
const defaultProps = {
  children: 'children',
  label: 'title',
  disabled: 'disabled'
}
onMounted(() => {
  loadData();
  showCheckBox.value = props.checkbox;
  if (props.disabled) {
    showCheckBox.value = false
  }
})

//监听变化
watch(() => props.roleId, () => {
  if (props.disabled) {
    proxy.$http.post("/user-center/menu/roleTreeData", {
      roleId: props.roleId
    }).then((res: any) => {
      compData.value = res.data;
    });
  } else {
    proxy.$http.post("/user-center/menu/menuTreeIds", {
      roleId: props.roleId
    }).then((res: any) => {
      compValue.value = res.data;
      emit("update:value", res.data.toLocaleString())
    });
  }

}, {
  // deep: true // 可以不写
})
// @ts-ignore
let {proxy} = getCurrentInstance()

//加载数据
function loadData() {
  if (!props.disabled) {
    proxy.$http.post("/user-center/menu/menuTree", {}).then((res: any) => {
      compData.value = res.data;
    });
  }
}

function checkEvent(checkNode: any, checkNodes: any) {
  //emit("update:value", checkNodes.checkedKeys.toLocaleString())
  // 获取当前节点是否被选中
  const isChecked = treeRef.value.getNode(checkNode).checked
  // 如果当前节点被选中，则遍历上级节点和下级子节点并选中，如果当前节点取消选中，则遍历下级节点并取消选中
  if (isChecked) {
    // 判断是否有上级节点，如果有那么遍历设置上级节点选中
    checkNode.parentKey && setParentChecked(checkNode.parentKey)
    // 判断该节点是否有下级节点，如果有那么遍历设置下级节点为选中
    checkNode.children && setChildreChecked(checkNode.children, true)

  } else {
    // 如果节点取消选中，则取消该节点下的子节点选中
    checkNode.children && setChildreChecked(checkNode.children, false)
    if (checkNode.children) {
      getKeys();
    }
  }

  function setParentChecked(parentKey: string) {
    // 获取该id的父级node
    const parentNode = treeRef.value.getNode(parentKey)
    // 如果该id的父级node存在父级id则继续遍历
    parentNode && parentNode.data && parentNode.data.parentKey && setParentChecked(parentNode.data.parentKey)
    //  设置该id的节点为选中状态
    treeRef.value.setChecked(parentKey, true)
    getKeys();
  }

  function setChildreChecked(node: any, isChecked: boolean) {
    node.forEach((item: any) => {
      item.children && setChildreChecked(item.children, isChecked)
      treeRef.value.setChecked(item.key, isChecked)
      getKeys();
    })
  }
}

function getKeys() {
  let filterKeys = treeRef.value.getCheckedKeys().map((item: any) => {
    return item;
  })
  emit("update:value", filterKeys + "")
}

function nodeClick(v1:any){
  if(!props.checkbox){
    emit("update:value", v1.key)
  }
}

</script>

<style scoped>

</style>
